#include "DataStructure/Input/Element/CONM1Data.h"

#include <cstddef>

#include "Utility/Algebra/Matrix.h"

#include "DataStructure/Common/Integer.h"
#include "DataStructure/Common/Validation.h"
#include "DataStructure/Input/Element/ElementBase.h"

using namespace SG::DataStructure::FEM;

CONM1Data::CONM1Data () = default;

CONM1Data::CONM1Data (SG::DataStructure::Common::I64 eId) : ElementBase (eId)
{}

/**
 * @brief 填充上三角矩阵
 *
 * 根据CONM1Data类的成员变量进行赋值，填充一个6x6的上三角矩阵，。
 *
 * @return 填充后的满阵
 */
SG::Algebra::Matrixd CONM1Data::FillUperTriangle () const
{
    SG::Algebra::Matrixd mass (6, 6);

    // 填充下三角
    mass (0, 0) = m_m1[0];

    mass (1, 0) = m_m2[0];
    mass (1, 1) = m_m2[1];

    mass (2, 0) = m_m3[0];
    mass (2, 1) = m_m3[1];
    mass (2, 2) = m_m3[2];

    mass (3, 0) = m_m4[0];
    mass (3, 1) = m_m4[1];
    mass (3, 2) = m_m4[2];
    mass (3, 3) = m_m4[3];

    mass (4, 0) = m_m5[0];
    mass (4, 1) = m_m5[1];
    mass (4, 2) = m_m5[2];
    mass (4, 3) = m_m5[3];
    mass (4, 4) = m_m5[4];

    mass (5, 0) = m_m6[0];
    mass (5, 1) = m_m6[1];
    mass (5, 2) = m_m6[2];
    mass (5, 3) = m_m6[3];
    mass (5, 4) = m_m6[4];
    mass (5, 5) = m_m6[5];

    // 填充上三角
    for (std::size_t i = 0; i < 6; ++i)
    {
        for (std::size_t j = i + 1; j < 6; ++j)
        {
            mass (i, j) = mass (j, i);
        }
    }

    return mass;
}

/// @brief 判断两个CONM1Data是否相等
/// @param a
/// @param b
/// @return
bool SG::DataStructure::FEM::operator== (const CONM1Data& a, const CONM1Data& b)
{
    if (a.m_id != b.m_id)
    {
        return false;
    }
    if (a.m_g[0] != b.m_g[0])
    {
        return false;
    }
    if (a.m_cId != b.m_cId)
    {
        return false;
    }
    if (a.m_domainId != b.m_domainId)
    {
        return false;
    }
    if (!SG::DataStructure::Common::isNear (a.m_m1[0], b.m_m1[0]) || !SG::DataStructure::Common::isNear (a.m_m2[0], b.m_m2[0])
        || !SG::DataStructure::Common::isNear (a.m_m2[1], b.m_m2[1]) || !SG::DataStructure::Common::isNear (a.m_m3[0], b.m_m3[0])
        || !SG::DataStructure::Common::isNear (a.m_m3[1], b.m_m3[1]) || !SG::DataStructure::Common::isNear (a.m_m3[2], b.m_m3[2])
        || !SG::DataStructure::Common::isNear (a.m_m4[0], b.m_m4[0]) || !SG::DataStructure::Common::isNear (a.m_m4[1], b.m_m4[1])
        || !SG::DataStructure::Common::isNear (a.m_m4[2], b.m_m4[2]) || !SG::DataStructure::Common::isNear (a.m_m4[3], b.m_m4[3])
        || !SG::DataStructure::Common::isNear (a.m_m5[0], b.m_m5[0]) || !SG::DataStructure::Common::isNear (a.m_m5[1], b.m_m5[1])
        || !SG::DataStructure::Common::isNear (a.m_m5[2], b.m_m5[2]) || !SG::DataStructure::Common::isNear (a.m_m5[3], b.m_m5[3])
        || !SG::DataStructure::Common::isNear (a.m_m5[4], b.m_m5[4]) || !SG::DataStructure::Common::isNear (a.m_m6[0], b.m_m6[0])
        || !SG::DataStructure::Common::isNear (a.m_m6[1], b.m_m6[1]) || !SG::DataStructure::Common::isNear (a.m_m6[2], b.m_m6[2])
        || !SG::DataStructure::Common::isNear (a.m_m6[3], b.m_m6[3]) || !SG::DataStructure::Common::isNear (a.m_m6[4], b.m_m6[4])
        || !SG::DataStructure::Common::isNear (a.m_m6[5], b.m_m6[5]))
    {
        return false;
    }
    return true;
}